package com.yt.Insurance.server.service;

import com.yt.Insurance.models.dto.InsurancePolicyDTO;
import com.yt.Insurance.models.vo.InsurancePolicyVO;
import com.yt.Insurance.models.bo.PolicyQueryBO;
import com.yt.Insurance.models.entity.InsurancePolicy;
import com.yt.Insurance.server.mapper.InsurancePolicyMapper;
import com.yt.Insurance.models.service.InsurancePolicyService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yt.product.models.entity.InsuranceProduct;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.HashMap;

@Service
public class InsurancePolicyServiceImpl implements InsurancePolicyService {

    @Autowired
    private InsurancePolicyMapper policyMapper;

    // 状态映射表，模拟从sys_attribute表中获取数据
    private static final Map<Integer, String> STATUS_MAP = new HashMap<>();
    
    static {
        STATUS_MAP.put(16, "待审核");
        STATUS_MAP.put(17, "已生效");
        STATUS_MAP.put(18, "已拒保");
        STATUS_MAP.put(19, "已退保");
        STATUS_MAP.put(20, "已过期");
    }

    @Override
    @Transactional
    public InsurancePolicyVO createPolicy(InsurancePolicyDTO policyDTO) {
        // 1. 转换DTO为Entity
        InsurancePolicy policy = new InsurancePolicy();
        BeanUtils.copyProperties(policyDTO, policy);

        // 2. 设置默认值和生成保单编号
        policy.setPolicyNo(generatePolicyNo());
        policy.setStatusAttrId(16); // 默认待审核状态
        policy.setIsDelete((byte) 0);
        policy.setCreateTime(new Date());
        policy.setUpdateTime(new Date());

        // 3. 保存到数据库
        // 注意：需要确保传入的insurantId在数据库中存在，否则会违反外键约束
        // 在实际应用中，应该先创建用户（被保险人），然后使用其ID创建保单
        int result = policyMapper.insert(policy);
        if (result <= 0) {
            throw new RuntimeException("保单创建失败");
        }

        // 4. 转换为VO返回
        return convertToVO(policy);
    }

    @Override
    public InsurancePolicyVO getPolicyById(Integer policyId) {
        InsurancePolicy policy = policyMapper.selectByPrimaryKey(policyId);
        return policy != null ? convertToVO(policy) : null;
    }

    @Override
    public PageInfo<InsurancePolicyVO> queryPolicyPage(PolicyQueryBO queryBO) {
        PageHelper.startPage(queryBO.getPageNum(), queryBO.getPageSize());
        List<InsurancePolicy> policies = policyMapper.selectByCondition(queryBO);

        List<InsurancePolicyVO> voList = policies.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageInfo<>(voList);
    }

    @Override
    @Transactional
    public boolean updatePolicyStatus(Integer policyId, Integer statusAttrId, String rejectReason) {
        InsurancePolicy policy = policyMapper.selectByPrimaryKey(policyId);
        if (policy == null) {
            return false;
        }

        policy.setStatusAttrId(statusAttrId);
        policy.setRejectReason(rejectReason);
        policy.setUpdateTime(new Date());

        // 如果审核通过，设置生效时间和终保时间
        if (isApprovedStatus(statusAttrId)) {
            policy.setInsuranceTime(new Date());
            policy.setEndTime(calculateEndTime(policy.getInsuranceTime(), policy.getInsuranceTerm()));
        }

        return policyMapper.updateByPrimaryKeySelective(policy) > 0;
    }

    @Override
    @Transactional
    public boolean surrenderPolicy(Integer policyId, String surrenderReason, BigDecimal refundAmount) {
        InsurancePolicy policy = policyMapper.selectByPrimaryKey(policyId);
        if (policy == null) {
            return false;
        }

        // 设置退保相关信息
        policy.setStatusAttrId(getSurrenderStatusId()); // 假设退保状态ID
        policy.setSurrenderTime(new Date());
        policy.setSurrenderReason(surrenderReason);
        policy.setRefundAmount(refundAmount);
        policy.setUpdateTime(new Date());

        return policyMapper.updateByPrimaryKeySelective(policy) > 0;
    }

    // 转换为VO
    private InsurancePolicyVO convertToVO(InsurancePolicy policy) {
        InsurancePolicyVO vo = new InsurancePolicyVO();
        BeanUtils.copyProperties(policy, vo);
        // 设置产品名称
        if (policy.getProductId() != null && policy.getProductName() != null) {
            // 由于已经在SQL查询中通过联表查询获取了产品名称，直接使用即可
            vo.setProductName(policy.getProductName());
        }
        
        // 设置状态名称
        if (policy.getStatusAttrId() != null) {
            vo.setStatusName(STATUS_MAP.getOrDefault(policy.getStatusAttrId(), "未知状态"));
        }
        
        return vo;
    }

    // 生成保单编号
    private String generatePolicyNo() {
        // 实现保单编号生成逻辑，例如：前缀+时间戳+随机数
        return "POL" + System.currentTimeMillis() + (int)(Math.random() * 1000);
    }

    // 计算终保时间
    private Date calculateEndTime(Date insuranceTime, Integer term) {
        // 实现根据投保时间和期限计算终保时间的逻辑
        return new Date(insuranceTime.getTime() + term * 30L * 24 * 60 * 60 * 1000); // 简化处理，每月按30天计算
    }

    // 判断是否是审核通过状态
    private boolean isApprovedStatus(Integer statusAttrId) {
        // 实际应根据业务定义判断，这里假设17是审核通过状态
        return statusAttrId != null && statusAttrId == 17;
    }

    // 获取退保状态ID
    private Integer getSurrenderStatusId() {
        // 实际应根据业务定义返回
        return 19;
    }
}